home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d21
/
dvmulti.arc
/
SLAVE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-10-25
|
8KB
|
329 lines
/* Slave program for DESQview tests
1989 MIPS Magazine / Mark Mallett
*/
#include <stdio.h>
#include <fcntl.h>
#include <dvapi.h>
#include "dvmulti.h"
/* Resolution of the timer (ticks per second) */
#define TIMERES 100
/* Timer ticks per day */
#define DAYTIMER ((long)(60L*60*24*TIMERES))
/* External routines */
extern char *malloc();
/* Forward routines */
ULONG timenow();
/* Local Variables */
static char **Buflist; /* Ptrs to buffers */
static int BufN; /* Current I/O buffer */
static char Filename[100];
static char IotestF; /* If doing I/O test */
static int Iofd; /* FD for test file */
static ULONG Kbd_main; /* Main keyboard object handle */
static ULONG Mal_main; /* Main mailbox */
static ULONG Mal_super; /* Supervisor's mailbox */
static ULONG Tim_main; /* for timer */
static ULONG Tim_tod; /* Time-of-day timer */
static ULONG Time_all; /* Ticks spent in program */
static ULONG Time_cpu; /* Ticks spent in CPU section */
static ULONG Time_read; /* Ticks spent in I/O read */
static ULONG Time_write; /* Ticks spent in I/O write */
static ULONG Tsk_super; /* Supervisor's task handle */
static ULONG Win_main; /* Main window */
static CNMSG Cnfmsg; /* The configuration message */
static RSMSG Rptmsg; /* The report message */
main()
{
int version; /* Version of current dv */
version = api_init();
if ( version < DVVER ) {
fprintf( stderr, "DESQview version %d.%02d or later required.\n",
DVVER/256, DVVER%256 );
}
else {
api_level( DVVER );
slave();
}
if ( version != 0 )
api_exit();
}
/* The functional main program of the supervisor program. Called after
DESQview environment is established. */
slave()
{
int msgcode; /* Message code... */
int msgL; /* Mail message length */
char *msgP; /* Mail message ptr */
long loopC; /* Execution loop counter */
/* Get handles to main window, keyboard, mailbox, and timers. */
Win_main = win_me();
Kbd_main = key_me();
Mal_main = mal_me();
Tim_main = tim_new();
Tim_tod = tim_new();
/* Put up startup message in our window */
win_erase( Win_main );
win_printf( Win_main, "Need CONFIG\n" );
/* Wait for configuration message from supervisor */
for( ; ; ) {
msgcode = mal_read( Mal_main, &msgP, &msgL );
if ( msgcode == MSG_CONFIG )
break;
}
/* Perform configuration */
win_erase( Win_main );
win_printf( Win_main, "Init...\n" );
if ( !configure( msgP, msgL ) )
return;
/* Ready to go... send ready message. */
mal_addto( Mal_super, NULL, 0, MSG_READY );
win_erase( Win_main );
win_printf( Win_main, "Need GO\n" );
/* Wait for GO message from supervisor */
for( ; ; ) {
msgcode = mal_read( Mal_main, &msgP, &msgL );
if ( msgcode == MSG_GO )
break;
}
/* Run now */
win_erase( Win_main );
win_printf( Win_main, "Running...\n" );
/* Get start time */
Time_all = timenow();
for( loopC = 0; ; ++loopC ) {
/* Check for stop request */
if ( mal_sizeof( Mal_main ) != 0 ) {
do
msgcode = mal_read( Mal_main, &msgP, &msgL );
while( ( msgcode != MSG_STOP ) &&
( mal_sizeof( Mal_main ) != 0 ) );
if ( msgcode == MSG_STOP )
break;
}
/* Perform I/O function */
iotest();
/* Perform cpu test */
cputest();
/* Sleep for the designated interval */
if ( Cnfmsg.cm_sleep != 0 ) {
tim_addto( Tim_main, Cnfmsg.cm_sleep );
tim_read( Tim_main );
}
}
/* All done */
Time_all = timenow() - Time_all;
/* Report now */
win_erase( Win_main );
win_printf( Win_main, "Reporting...\n" );
Rptmsg.rm_loopC = (long)loopC;
report();
}
/* Perform the I/O test */
iotest()
{
extern int read();
extern int write();
if ( !IotestF )
return;
if ( Cnfmsg.cm_readF )
io_run( read, &Time_read );
if ( Cnfmsg.cm_writeF )
io_run( write, &Time_write );
}
io_run( iortc, timeP )
int (*iortc)(); /* I/O routine to call */
ULONG *timeP; /* Ptr to timer counter */
{
int block;
long loopC; /* I/O loop counter */
long filepos; /* File position to use */
ULONG timer; /* Timer counter */
char *bufP;
/* Get start time */
timer = timenow();
/* If sequential I/O, start at the beginning */
if ( Cnfmsg.cm_seqF )
lseek( Iofd, filepos = 0L, 0 );
/* Perform the specified number of loops */
for( loopC = 0; loopC < Cnfmsg.cm_ioC; ++loopC ) {
/* Select next buffer */
if ( ++BufN == Cnfmsg.cm_iobufC )
BufN = 0;
bufP = Buflist[BufN];
/* Select appropriate file position */
if ( Cnfmsg.cm_seqF ) {
if ( filepos + Cnfmsg.cm_xsize >= Cnfmsg.cm_fsize )
lseek( Iofd, filepos = 0L, 0 );
filepos += Cnfmsg.cm_xsize; /* Next position */
}
else {
/* Choose a random file position */
block = rand() % (int)( Cnfmsg.cm_fsize/Cnfmsg.cm_xsize -1 );
filepos = block * Cnfmsg.cm_xsize;
lseek( Iofd, filepos, 0 );
}
/* Perform the disk transfer */
(*iortc)( Iofd, bufP, Cnfmsg.cm_xsize );
}
/* Accumulate the elapsed time */
*timeP = *timeP + (timenow() - timer);
}
/* Perform the CPU test */
cputest()
{
int i, j, k;
ULONG timer; /* Time in this routine */
if ( Cnfmsg.cm_cpuC == 0 )
return;
timer = timenow(); /* Start the timer */
for( i = 0; i < Cnfmsg.cm_cpuC; ++i )
for( j = 0; j < 1000; ++j )
k = rand();
Time_cpu = Time_cpu + ( timenow() - timer );
}
/* Process configuration message, do initialization... */
configure( cmsgP, cmsgL )
CNMSG *cmsgP; /* Ptr to configure msg */
int cmsgL; /* Length of the message */
{
int i;
long size;
char kbuf[1024];
/* Get sender of config message */
Tsk_super = mal_addr( Mal_main );
Mal_super = mal_of( Tsk_super );
/* Make sure configuration message is (at least) the right size */
if ( cmsgL < sizeof(CNMSG) )
return (FALSE);
/* Stash configuration parameters for later use */
memcpy( &Cnfmsg, cmsgP, sizeof(CNMSG) );
/* Setup for I/O if we need to do any */
if ( ( Cnfmsg.cm_readF || Cnfmsg.cm_writeF ) &&
( Cnfmsg.cm_ioC != 0 ) ) {
IotestF = TRUE;
/* Allocate the buffers */
Buflist = (char **)malloc( Cnfmsg.cm_iobufC * sizeof(char *) );
for( i = 0; i < Cnfmsg.cm_iobufC; ++i )
Buflist[i] = (char *)malloc( Cnfmsg.cm_xsize );
BufN = 0;
/* Make the data file */
sprintf( &Filename[0], "Slave%03d.dat", Cnfmsg.cm_taskN );
Iofd = open( &Filename[0], O_RDWR|O_CREAT|O_BINARY, 0666 );
if ( Iofd < 0 )
return( FALSE );
/* Populate the file */
for( size = 0; size < Cnfmsg.cm_fsize; size += 1024 )
write( Iofd, &kbuf[0], 1024 );
}
else
IotestF = FALSE;
/* Start the time-of-day timer running */
tim_write( Tim_tod, (long)(DAYTIMER -1) );
return( TRUE );
}
/* Send a report back to the supervisor task */
report()
{
float x;
win_erase( Win_main );
win_printf( Win_main, "loops=%d\n", (int)Rptmsg.rm_loopC );
Rptmsg.rm_tick = TIMERES;
Rptmsg.rm_alltime = Time_all;
Rptmsg.rm_readtime = Time_read;
Rptmsg.rm_writetime = Time_write;
Rptmsg.rm_cputime = Time_cpu;
/* Rptmsg.rm_alltime = ((float)Time_all)/(float)TIMERES;
Rptmsg.rm_readtime = ((float)Time_read)/(float)TIMERES;
Rptmsg.rm_writetime = ((float)Time_write)/(float)TIMERES;
Rptmsg.rm_cputime = ((float)Time_cpu)/(float)TIMERES;
*/
mal_addto( Mal_super, &Rptmsg, sizeof(RSMSG), MSG_REPORT );
}
/* Get time now, from the time-of-day timer */
ULONG
timenow()
{
return( DAYTIMER - tim_len( Tim_tod ) );
}